package com.weilele.mvvm.utils.thread

import androidx.lifecycle.LifecycleOwner
import com.weilele.mvvm.base.helper.ILifecycleObserver
import com.weilele.mvvm.utils.coroutine.createCoroutine
import com.weilele.mvvm.utils.coroutine.launchOnThread
import com.weilele.mvvm.utils.coroutine.launchOnUi
import com.weilele.mvvm.utils.logI
import kotlinx.coroutines.*

/**
 * 自动循环任务
 */
class TickTask(
    val time: Long,
    val onThread: Boolean = false,
    val runnable: suspend CoroutineScope.() -> Unit
) :
    ILifecycleObserver {
    companion object {
        /**
         * 启动轮询,必须手动取消，否则内存泄露
         */
        fun start(
            time: Long = 1000L,
            onThread: Boolean = false,
            block: suspend CoroutineScope.() -> Unit
        ): TickTask {
            return TickTask(time, onThread, block).also {
                it.start()
            }
        }

        /**
         * 带有生命周期的启动
         */
        fun startWithLifecycleOwner(
            owner: LifecycleOwner,
            time: Long = 1000L,
            onThread: Boolean = false,
            block: suspend CoroutineScope.() -> Unit
        ): TickTask {
            val task = start(time, onThread, block)
            owner.lifecycle.addObserver(task)
            return task
        }

        /**
         * 停止轮询
         */
        fun TickTask.stop() {
            cancel()
        }
    }

    private val coroutineScope = createCoroutine()

    /**
     * job
     *
     */
    private var job: Job? = null

    /**
     * run
     */
    @Synchronized
    fun start() {
        if (isRunning) {
            logI { "TickTask已经启动,无需再启动" }
            return
        }
        val block: suspend CoroutineScope.() -> Unit = {
            while (isActive) {
                runnable.invoke(this)
                delay(time)
            }
        }
        job = if (onThread) {
            coroutineScope.launchOnThread(block = block)
        } else {
            coroutineScope.launchOnUi(block = block)
        }
    }

    /**
     * 是否正运行
     */
    val isRunning
        get() = job?.isActive == true

    /**
     * 取消回调
     */
    fun cancel() {
        onlyCancelJob()
        job = null
    }

    /**
     * 生命周期可见
     */
    override fun onStart() {
        super.onStart()
        //如果取消的时候正在运行，则自动恢复
        //如果用户取消，job是null，否则是自动取消，需要恢复
        if (job != null) {
            logI { "onStart 自动恢复TickTask" }
            start()
        }
    }

    /**
     * 生命周期不可见
     */
    override fun onStop() {
        super.onStop()
        onlyCancelJob()
    }

    override fun onDestroy() {
        super.onDestroy()
        cancel()
        if (coroutineScope.isActive) {
            coroutineScope.cancel()
        }
    }

    /**
     * 取消job，变量不赋值为null，
     */
    private fun onlyCancelJob() {
        if (isRunning) {
            job?.cancel()
        }
    }
}
